package com.firmye.codereposboot.task;

import com.firmye.codereposboot.dao.PostMapperDao;
import com.firmye.codereposboot.model.postmapper.pojo.PostMapper;
import com.firmye.codereposboot.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Configuration
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class PostalCodeTask extends QuartzJobBean {
    @Autowired
    Scheduler scheduler;

    public JobDetail taskDetail() {
        return JobBuilder.newJob(PostalCodeTask.class).withIdentity("PostalCodeTask").storeDurably().build();
    }

    public Trigger taskTrigger() {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0 * * ?");
        return TriggerBuilder.newTrigger().forJob(taskDetail())
                .withIdentity("PostalCodeTask")
                //.withSchedule(scheduleBuilder)
                .startNow()
                .build();
    }

    @Bean
    public Date addPostalCodeTask() throws SchedulerException {
        return scheduler.scheduleJob(taskDetail(),taskTrigger());
    }

    @Autowired
    private PostMapperDao postMapperDao;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("=====> 开始爬取邮编信息");
        long startTime = System.currentTimeMillis();

        String root = "https://gbr.postcodebase.com";
        reptile(root,"/zh-hans/all?page=1020");   // 17506

        log.info("=====> 结束邮编信息爬取，耗时 " + (System.currentTimeMillis() - startTime) + " ms");
    }

    public void reptile(String root,String path){
        String url = root + path;
        Document doc = null;
        try {
            log.info("=====> 即将获取连接：" + url);
            doc = getDocument(url);

            Elements els = doc.select("td.views-field.views-field-field-id");
            long startTime = System.currentTimeMillis();
            List mappers = new ArrayList<>();
            for(Element el:els){
                Element element = el.select("a").first();
                url = root + element.attr("href");

                log.info("=====> 即将获取子连接：" + url);
                Document subDoc = null;
                try {
                    subDoc = getDocument(url);
                } catch (Exception e){
                    log.error("=====> 无法获取链接：" + url);
                    continue;
                }

                element = subDoc.select("#page-title").first();
                String[] tmp = element.text().split(":");

                PostMapper mapper = new PostMapper();
                mapper.setPostalCode(tmp[1].trim());
                tmp = tmp[0].split(",");
                mapper.setCountryCode("GBR");
                mapper.setProvince(tmp[tmp.length - 1].trim());
                mapper.setCity(tmp[tmp.length - 2].trim());
                mapper.setRegion(tmp[tmp.length - 3].trim());
                mapper.setUpdatedTime(new Date());

                log.info("=====> " + mapper);
                mappers.add(mapper);
            }
            postMapperDao.batchInsert(mappers);
            log.info("=====> 单页处理完毕，耗时 " + (System.currentTimeMillis() - startTime) + " ms");
            // 本页处理完毕

            Element next = doc.select("li.pager-next.last").first();
            if(null != next){
                Element element = next.select("a").first();
                path = element.attr("href");
                reptile(root,path);
            }
        } catch (Exception e) {
            log.error("=====> 链接[" + url + "]获取失败，将重新获取");
            reptile(root,path);
        }
    }

    public Document getDocument(String url) {
        try {
            return Jsoup.connect(url).get();
        } catch (Exception e1) {
            log.error("=====> Jsoup链接异常，将使用JDK链接：" + url);
            try {
                return Jsoup.parse(HttpUtil.doGet(url));
            } catch (Exception e2) {
                return getDocument(url);
            }
        }
    }
}
